package org.lazycoder.logger.module;

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

import javax.imageio.ImageIO;

import org.lazycoder.logger.Event;
import org.lazycoder.logger.EventLogger;
import org.lazycoder.logger.Module;

/**
 * An EventLogger Module to log simple text entries and screen cap each time one
 * is made.
 * 
 * @author Matthew Bayliss
 */
public class Journal extends Module {
	/** The singleton instance of this class */
	private volatile static Journal	instance	= null;
	/** Generates a warning if tempdirectory is inaccessible */
	private boolean					warned		= false;

	/**
	 * Get the singleton instance of this class. This method will also create
	 * the object if it does not yet exist. This is implemented in a threadsafe
	 * manner. The actual instantiation of EventLogger is done in a synchronised
	 * block which is only entered into if the instance variable is null.
	 * 
	 * @return the event logger object.
	 */
	public static Journal getInstance() {
		if (instance == null) {
			synchronized (Journal.class) {
				if (instance == null) {
					instance = new Journal();
				}
			}
		}
		return instance;
	}

	private Robot	robot;

	private Journal() {
		super();
		try {
			robot = new Robot();
		} catch (AWTException e) {
			System.err
					.println("Cannot create JavaBot. No printscreens will be captured");
		}
	}

	@Override
	public String getName() {
		return "Journal";
	}

	/**
	 * Log an event with the message text
	 * 
	 * @param text
	 *            the message to log.
	 */
	public void log(String text) {
		try {
			Event event = new Event(text, new Date());
			Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit()
					.getScreenSize());

			BufferedImage image = robot.createScreenCapture(rect);
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			String name = String
					.valueOf(md.digest(image.toString().getBytes()));
			// TODO this should MD data... not to string
			File temp = new File(System.getProperty("java.io.tmpdir"));
			if (temp.canWrite()) {
				File imageFile = new File(temp.getAbsolutePath() + "/" + name
						+ ".png");
				ImageIO.write(image, "png", imageFile);
				event.addFile(imageFile);
			} else {
				if (!warned) {
					System.err.println("Cannot access temp directory.");
					Event e = new Event(
							"Journal cannot access the directory "
									+ temp.getAbsolutePath()
									+ ". This is required for screenshots to work. Am i sandboxed?",
							new Date());
					EventLogger.getInstance().update(Journal.getInstance(), e);
					warned = true;
				}
			}
			EventLogger.getInstance().update(Journal.getInstance(), event);
		} catch (IOException e) {
			System.err.println("Error outputting file");
		} catch (NoSuchAlgorithmException e) {
			System.err.println("Invalid MD algorithm");
		}
	}
}
